package sg.simple.snmp.provider.impl;

import isnmp.ui.dto.NetworkInfo;
import isnmp.ui.dto.NetworkInfo.NETWORK_PROPERTY;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.util.TableEvent;

public class NetworkInfoProvider extends SNMPTableReader {

	/** Conceptual entry to mark the index in table */
	private String interfaceIndexOid = "1.3.6.1.2.1.2.2.1.1";

	private String interfaceDescOid = "1.3.6.1.2.1.2.2.1.2";

	/** Average load percentage over the last minute */
	private String interfaceMTUOid = "1.3.6.1.2.1.2.2.1.4";

	private String interfacePhysicalAddressOid = "1.3.6.1.2.1.2.2.1.6";

	private String estimatedBandWidthOid = "1.3.6.1.2.1.2.2.1.5";

	private String adminStatusOid = "1.3.6.1.2.1.2.2.1.7";

	private String operationalStatusOid = "1.3.6.1.2.1.2.2.1.8";

	private String interfaceTypeOid = "1.3.6.1.2.1.2.2.1.3";

	Logger logger = Logger.getLogger(NetworkInfoProvider.class);

	public List<NetworkInfo> retrieve(Snmp session, Target target) {

		OID interfaceIndex = new OID(interfaceIndexOid);
		OID interfaceDesc = new OID(interfaceDescOid);
		OID interfaceMTU = new OID(interfaceMTUOid);
		OID interfacePhysicalAddress = new OID(interfacePhysicalAddressOid);
		OID estimatedBandWidth = new OID(estimatedBandWidthOid);
		OID adminStatus = new OID(adminStatusOid);
		OID operationalStatus = new OID(operationalStatusOid);
		OID interfaceType = new OID(interfaceTypeOid);

		List<NetworkInfo> networkInformationList = new ArrayList<NetworkInfo>();

		List<TableEvent> networkInfoTable = this.readTable(session, target,
				new OID[] { interfaceIndex, interfaceType, interfaceDesc,
						interfaceMTU, interfacePhysicalAddress,
						estimatedBandWidth, adminStatus, operationalStatus });

		for (TableEvent aRow : networkInfoTable) {

			if (aRow.isError()) {
				continue;
			}

			String index = "";
			String type = "";
			String desc = "";
			String mtu = "";
			String physicalAddr = "";
			String bandWidth = "";
			String admin = "";
			String oprStatus = "";

			for (VariableBinding v : aRow.getColumns()) {

				if (matches(interfaceIndex, v)) {
					index = v.getVariable().toString();
					continue;
				}
				if (matches(interfaceType, v)) {
					type = getInterfaceType(v.getVariable().toString());
					continue;
				}

				if (matches(interfaceDesc, v)) {
					desc = v.getVariable().toString();
					continue;
				}
				if (matches(interfaceMTU, v)) {
					mtu = v.getVariable().toString();
					continue;
				}

				if (matches(interfacePhysicalAddress, v)) {
					physicalAddr = v.getVariable().toString();
					continue;
				}

				if (matches(estimatedBandWidth, v)) {
					bandWidth = v.getVariable().toString();
					continue;
				}

				if (matches(adminStatus, v)) {
					admin = getAdminStatus(v.getVariable().toString());
					continue;
				}

				if (matches(operationalStatus, v)) {
					oprStatus = getOperationalStatus(v.getVariable().toString());
					continue;
				}

			}

			NetworkInfo info = new NetworkInfo();
			info.putValue(NETWORK_PROPERTY.INDEX, index);
			info.putValue(NETWORK_PROPERTY.TYPE, type);
			info.putValue(NETWORK_PROPERTY.DESCRIPTION, desc);
			info.putValue(NETWORK_PROPERTY.MTU, mtu);
			info.putValue(NETWORK_PROPERTY.PHYSICAL_ADDRESS, physicalAddr);
			info.putValue(NETWORK_PROPERTY.ESTIMATED_BANDWIDTH, bandWidth);
			info.putValue(NETWORK_PROPERTY.ADMINISTRATION_STATUS, admin);
			info.putValue(NETWORK_PROPERTY.OPERATIONAL_STATUS, oprStatus);

			networkInformationList.add(info);
		}

		return networkInformationList;

	}

	private String getInterfaceType(String code) {

		String ret = interfaceTypes.get(code);
		return ret == null ? code : ret;
	}

	private String getAdminStatus(String code) {
		String ret = adminStates.get(code);
		return ret == null ? code : ret;

	}

	private String getOperationalStatus(String code) {
		String ret = oprStates.get(code);
		return ret == null ? code : ret;

	}

	static Map<String, String> interfaceTypes = new HashMap<String, String>();
	static Map<String, String> adminStates = new HashMap<String, String>();
	static Map<String, String> oprStates = new HashMap<String, String>();

	static {
		adminStates.put("1", "up");
		adminStates.put("2", "down");
		adminStates.put("3", "testing");

		oprStates.put("1", "up");
		oprStates.put("2", "down");
		oprStates.put("3", "testing");
		oprStates.put("4", "unknown");
		oprStates.put("5", "dormant");
		oprStates.put("6", "notPresent");
		oprStates.put("7", "lowerLayerDown");

		interfaceTypes.put("1", "other");
		interfaceTypes.put("2", "regular1822");
		interfaceTypes.put("3", "hdh1822");
		interfaceTypes.put("4", "ddnX25");
		interfaceTypes.put("5", "rfc877x25");
		interfaceTypes.put("6", "ethernetCsmacd");
		interfaceTypes.put("7", "iso88023Csmacd");
		interfaceTypes.put("8", "iso88024TokenBus");
		interfaceTypes.put("9", "iso88025TokenRing");
		interfaceTypes.put("10", "iso88026Man");
		interfaceTypes.put("11", "starLan");
		interfaceTypes.put("12", "proteon10Mbit");
		interfaceTypes.put("13", "proteon80Mbit");
		interfaceTypes.put("14", "hyperchannel");
		interfaceTypes.put("15", "fddi");
		interfaceTypes.put("16", "lapb");
		interfaceTypes.put("17", "sdlc");
		interfaceTypes.put("18", "ds1");
		interfaceTypes.put("19", "e1");
		interfaceTypes.put("20", "basicISDN");
		interfaceTypes.put("21", "primaryISDN");
		interfaceTypes.put("22", "propPointToPointSerial");
		interfaceTypes.put("23", "ppp");
		interfaceTypes.put("24", "softwareLoopback");
		interfaceTypes.put("25", "eon");
		interfaceTypes.put("26", "ethernet3Mbit");
		interfaceTypes.put("27", "nsip");
		interfaceTypes.put("28", "slip");
		interfaceTypes.put("29", "ultra");
		interfaceTypes.put("30", "ds3");
		interfaceTypes.put("31", "sip");
		interfaceTypes.put("32", "frameRelay");
		interfaceTypes.put("33", "rs232");
		interfaceTypes.put("34", "para");
		interfaceTypes.put("35", "arcnet");
		interfaceTypes.put("36", "arcnetPlus");
		interfaceTypes.put("37", "atm");
		interfaceTypes.put("38", "miox25");
		interfaceTypes.put("39", "sonet");
		interfaceTypes.put("40", "x25ple");
		interfaceTypes.put("41", "iso88022llc");
		interfaceTypes.put("42", "localTalk");
		interfaceTypes.put("43", "smdsDxi");
		interfaceTypes.put("44", "frameRelayService");
		interfaceTypes.put("45", "v35");
		interfaceTypes.put("46", "hssi");
		interfaceTypes.put("47", "hippi");
		interfaceTypes.put("48", "modem");
		interfaceTypes.put("49", "aal5");
		interfaceTypes.put("50", "sonetPath");
		interfaceTypes.put("51", "sonetVT");
		interfaceTypes.put("52", "smdsIcip");
		interfaceTypes.put("53", "propVirtual");
		interfaceTypes.put("54", "propMultiplexor");
		interfaceTypes.put("55", "ieee80212");
		interfaceTypes.put("56", "fibreChannel");
		interfaceTypes.put("57", "hippiInterface");
		interfaceTypes.put("58", "frameRelayInterconnect");
		interfaceTypes.put("59", "aflane8023");
		interfaceTypes.put("60", "aflane8025");
		interfaceTypes.put("61", "cctEmul");
		interfaceTypes.put("62", "fastEther");
		interfaceTypes.put("63", "isdn");
		interfaceTypes.put("64", "v11");
		interfaceTypes.put("65", "v36");
		interfaceTypes.put("66", "g703at64k");
		interfaceTypes.put("67", "g703at2mb");
		interfaceTypes.put("68", "qllc");
		interfaceTypes.put("69", "fastEtherFX");
		interfaceTypes.put("70", "channel");
		interfaceTypes.put("71", "ieee80211");
		interfaceTypes.put("72", "ibm370parChan");
		interfaceTypes.put("73", "escon");
		interfaceTypes.put("74", "dlsw");
		interfaceTypes.put("75", "isdns");
		interfaceTypes.put("76", "isdnu");
		interfaceTypes.put("77", "lapd");
		interfaceTypes.put("78", "ipSwitch");
		interfaceTypes.put("79", "rsrb");
		interfaceTypes.put("80", "atmLogical");
		interfaceTypes.put("81", "ds0");
		interfaceTypes.put("82", "ds0Bundle");
		interfaceTypes.put("83", "bsc");
		interfaceTypes.put("84", "async");
		interfaceTypes.put("85", "cnr");
		interfaceTypes.put("86", "iso88025Dtr");
		interfaceTypes.put("87", "eplrs");
		interfaceTypes.put("88", "arap");
		interfaceTypes.put("89", "propCnls");
		interfaceTypes.put("90", "hostPad");
		interfaceTypes.put("91", "termPad");
		interfaceTypes.put("92", "frameRelayMPI");
		interfaceTypes.put("93", "x213");
		interfaceTypes.put("94", "adsl");
		interfaceTypes.put("95", "radsl");
		interfaceTypes.put("96", "sdsl");
		interfaceTypes.put("97", "vdsl");
		interfaceTypes.put("98", "iso88025CRFPInt");
		interfaceTypes.put("99", "myrinet");
		interfaceTypes.put("100", "voiceEM");
		interfaceTypes.put("101", "voiceFXO");
		interfaceTypes.put("102", "voiceFXS");
		interfaceTypes.put("103", "voiceEncap");
		interfaceTypes.put("104", "voiceOverIp");
		interfaceTypes.put("105", "atmDxi");
		interfaceTypes.put("106", "atmFuni");
		interfaceTypes.put("107", "atmIma ");
		interfaceTypes.put("108", "pppMultilinkBundle");
		interfaceTypes.put("109", "ipOverCdlc ");
		interfaceTypes.put("110", "ipOverClaw ");
		interfaceTypes.put("111", "stackToStack ");
		interfaceTypes.put("112", "virtualIpAddress ");
		interfaceTypes.put("113", "mpc ");
		interfaceTypes.put("114", "ipOverAtm ");
		interfaceTypes.put("115", "iso88025Fiber ");
		interfaceTypes.put("116", "tdlc ");
		interfaceTypes.put("117", "gigabitEthernet ");
		interfaceTypes.put("118", "hdlc ");
		interfaceTypes.put("119", "lapf ");
		interfaceTypes.put("120", "v37 ");
		interfaceTypes.put("121", "x25mlp ");
		interfaceTypes.put("122", "x25huntGroup ");
		interfaceTypes.put("123", "trasnpHdlc ");
		interfaceTypes.put("124", "interleave ");
		interfaceTypes.put("125", "fast ");
		interfaceTypes.put("126", "ip ");
		interfaceTypes.put("127", "docsCableMaclayer ");
		interfaceTypes.put("128", "docsCableDownstream ");
		interfaceTypes.put("129", "docsCableUpstream ");
		interfaceTypes.put("130", "a12MppSwitch ");
		interfaceTypes.put("131", "tunnel ");
		interfaceTypes.put("132", "coffee ");
		interfaceTypes.put("133", "ces ");
		interfaceTypes.put("134", "atmSubInterface ");
		interfaceTypes.put("135", "l2vlan ");
		interfaceTypes.put("136", "l3ipvlan ");
		interfaceTypes.put("137", "l3ipxvlan ");
		interfaceTypes.put("138", "digitalPowerline ");
		interfaceTypes.put("139", "mediaMailOverIp ");
		interfaceTypes.put("140", "dtm ");
		interfaceTypes.put("141", "dcn ");
		interfaceTypes.put("142", "ipForward ");
		interfaceTypes.put("143", "msdsl ");
		interfaceTypes.put("144", "ieee1394 ");
		interfaceTypes.put("145", "if-gsn ");
		interfaceTypes.put("146", "dvbRccMacLayer ");
		interfaceTypes.put("147", "dvbRccDownstream ");
		interfaceTypes.put("148", "dvbRccUpstream ");
		interfaceTypes.put("149", "atmVirtual ");
		interfaceTypes.put("150", "mplsTunnel ");
		interfaceTypes.put("151", "srp ");
		interfaceTypes.put("152", "voiceOverAtm ");
		interfaceTypes.put("153", "voiceOverFrameRelay ");
		interfaceTypes.put("154", "idsl ");
		interfaceTypes.put("155", "compositeLink ");
		interfaceTypes.put("156", "ss7SigLink ");
		interfaceTypes.put("157", "propWirelessP2P ");
		interfaceTypes.put("158", "frForward ");
		interfaceTypes.put("159", "rfc1483 ");
		interfaceTypes.put("160", "usb ");
		interfaceTypes.put("161", "ieee8023adLag ");
		interfaceTypes.put("162", "bgppolicyaccounting ");
		interfaceTypes.put("163", "frf16MfrBundle ");
		interfaceTypes.put("164", "h323Gatekeeper ");
		interfaceTypes.put("165", "h323Proxy ");
		interfaceTypes.put("166", "mpls ");
		interfaceTypes.put("167", "mfSigLink ");
		interfaceTypes.put("168", "hdsl2 ");
		interfaceTypes.put("169", "shdsl ");
		interfaceTypes.put("170", "ds1FDL ");
		interfaceTypes.put("171", "pos ");
		interfaceTypes.put("172", "dvbAsiIn ");
		interfaceTypes.put("173", "dvbAsiOut ");
		interfaceTypes.put("174", "plc ");
		interfaceTypes.put("175", "nfas ");
		interfaceTypes.put("176", "tr008 ");
		interfaceTypes.put("177", "gr303RDT ");
		interfaceTypes.put("178", "gr303IDT ");
		interfaceTypes.put("179", "isup ");
		interfaceTypes.put("180", "propDocsWirelessMaclayer ");
		interfaceTypes.put("181", "propDocsWirelessDownstream ");
		interfaceTypes.put("182", "propDocsWirelessUpstream ");
		interfaceTypes.put("183", "hiperlan2 ");
		interfaceTypes.put("184", "propBWAp2Mp ");
		interfaceTypes.put("185", "sonetOverheadChannel ");
		interfaceTypes.put("186", "digitalWrapperOverheadChannel ");
		interfaceTypes.put("187", "aal2 ");
		interfaceTypes.put("188", "radioMAC ");
		interfaceTypes.put("189", "atmRadio ");
		interfaceTypes.put("190", "imt ");
		interfaceTypes.put("191", "mvl ");
		interfaceTypes.put("192", "reachDSL ");
		interfaceTypes.put("193", "frDlciEndPt ");
		interfaceTypes.put("194", "atmVciEndPt ");
		interfaceTypes.put("195", "opticalChannel ");
		interfaceTypes.put("196", "opticalTransport ");
		interfaceTypes.put("197", "propAtm ");
		interfaceTypes.put("198", "voiceOverCable ");
		interfaceTypes.put("199", "infiniband ");
		interfaceTypes.put("200", "teLink ");
		interfaceTypes.put("201", "q2931 ");
		interfaceTypes.put("202", "virtualTg ");
		interfaceTypes.put("203", "sipTg ");
		interfaceTypes.put("204", "sipSig ");
		interfaceTypes.put("205", "docsCableUpstreamChannel ");
		interfaceTypes.put("206", "econet ");
		interfaceTypes.put("207", "pon155 ");
		interfaceTypes.put("208", "pon622 ");
		interfaceTypes.put("209", "bridge ");
		interfaceTypes.put("210", "linegroup ");
		interfaceTypes.put("211", "voiceEMFGD ");
		interfaceTypes.put("212", "voiceFGDEANA ");
		interfaceTypes.put("213", "voiceDID ");
		interfaceTypes.put("214", "mpegTransport ");
		interfaceTypes.put("215", "sixToFour ");
		interfaceTypes.put("216", "gtp ");
		interfaceTypes.put("217", "pdnEtherLoop1 ");
		interfaceTypes.put("218", "pdnEtherLoop2 ");
		interfaceTypes.put("219", "opticalChannelGroup ");
		interfaceTypes.put("220", "homepna ");
		interfaceTypes.put("221", "gfp ");
		interfaceTypes.put("222", "ciscoISLvlan ");
		interfaceTypes.put("223", "actelisMetaLOOP ");
		interfaceTypes.put("224", "fcipLink ");
		interfaceTypes.put("225", "rpr ");
		interfaceTypes.put("226", "qam ");
		interfaceTypes.put("227", "lmp ");
		interfaceTypes.put("228", "cblVectaStar ");
		interfaceTypes.put("229", "docsCableMCmtsDownstream ");
		interfaceTypes.put("230", "adsl2 ");
		interfaceTypes.put("231", "macSecControlledIF ");
		interfaceTypes.put("232", "macSecUncontrolledIF ");
		interfaceTypes.put("233", "aviciOpticalEther ");
		interfaceTypes.put("234", "atmbond ");
		interfaceTypes.put("235", "voiceFGDOS ");
		interfaceTypes.put("236", "mocaVersion1 ");
		interfaceTypes.put("237", "ieee80216WMAN ");
		interfaceTypes.put("238", "adsl2plus ");
		interfaceTypes.put("239", "dvbRcsMacLayer ");
		interfaceTypes.put("240", "dvbTdm ");
		interfaceTypes.put("241", "dvbRcsTdma ");

	}

}
